package utils

import (
	"fmt"
	"gitee.com/lstack_light/go-light/internal/scaffold"
	"gitee.com/lstack_light/go-light/pkg/utils"
	"log"
	"os"
)

/**
  @author: light
  @since: 2023/9/6
  @desc: 命令行工具
*/

type cmd struct {
	ProjectName string
	FileName    string
	Dir         string
}

func help() {
	// 帮助命令
	fmt.Print(
		"Generate a scaffolding for a web framework (Go-Light) based on the go language implementation.\n\n",
		"Usage:\n",
		"\tgenerate <command> [arguments]\n\n",
		"The commands are:\n",
		"\t-project\tused in the specified project\n",
		"\t-name\t\tname of the generated file\n\n",
		"Use \"generate help\" for more information about a command.\n",
	)
}

func (c *cmd) AddCommand() bool {
	flags := make([]utils.Flag, 0)
	// 注册 -project 命令
	projectFlag := utils.Flag{
		Name:  "project",
		Usage: "项目名称",
	}
	// 注册 -name 命令
	fileNameFlag := utils.Flag{
		Name:  "name",
		Usage: "文件名称",
	}
	flags = append(flags, projectFlag, fileNameFlag)
	command := utils.Command{
		Flags: flags,
	}
	resultMap, err := command.ParseString()
	if nil != err {
		log.Fatal(err)
		return false
	}
	if projectName, ok := resultMap[projectFlag.Name]; ok && 0 == len(projectName) {
		fmt.Print("Error: You must specify a project name\n\n")
		help()
		return false
	}
	c.ProjectName = resultMap[projectFlag.Name]
	if fileName, ok := resultMap[fileNameFlag.Name]; ok && 0 == len(fileName) {
		fmt.Print("Error: You must specify the file name\n\n")
		help()
		return false
	}
	c.FileName = resultMap[fileNameFlag.Name]
	return true
}

func (c *cmd) GenerateTemplatesCommand() bool {
	// 生成模板
	return scaffold.Generate(c.Dir, c.ProjectName, c.FileName)
}

func (c *cmd) UpdateModCommand() bool {
	// 更新依赖
	updateModCommand := &utils.Command{
		Order: "go mod tidy",
		Dir:   c.Dir,
	}
	execResult, execErr := updateModCommand.Exec()
	if nil != execErr && 0 < len(execResult) {
		log.Fatal("已搭建完成脚手架 但自动更新 go-light 依赖失败（需要手动下载依赖即可启动 main.go）：", execResult)
		return false
	}
	log.Println("已搭建完成脚手架 并自动更新 go-light 依赖成功（可以直接启动 main.go）")
	return true
}

type CommandHandler struct {
	Current func() bool
	Next    *CommandHandler
}

func Execute() {
	// 获取当前程序运行的路径
	dir, err := os.Getwd()
	if err != nil {
		log.Fatal("无法获取当前程序路径：", err)
		return
	}
	command := cmd{
		Dir: dir,
	}
	// 链式注册命令
	updateModHandler := CommandHandler{
		Current: command.UpdateModCommand,
	}
	generateTemplatesHandler := CommandHandler{
		Current: command.GenerateTemplatesCommand,
		Next:    &updateModHandler,
	}
	commandHandler := CommandHandler{
		Current: command.AddCommand,
		Next:    &generateTemplatesHandler,
	}
	// 链式执行命令
	handler := commandHandler
	for handler.Current() {
		next := handler.Next
		if nil == next {
			break
		}
		handler = *next
	}
}
